package com.b2mining.daemons;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;

import com.b2mining.integration.helper.Constantes;
import com.b2mining.integration.helper.Helper;
import com.b2mining.integration.mq.IncorrectMessageFormatException;
import com.b2mining.integration.mq.MQIntegrationMessage;


/**
 * Clase que almacena la informacion del archivo(.xml o .csv)
 * @since (7/4/2003 1:12:20 PM)
 * @author Synopsis S.A. <BR>
 * Analista Programador: Miguel Lora G.
 */
public class XMLFile {
	Logger log = Logger.getLogger(this.getClass());
	private String fileName;
	private String completeFileName;
	private String codigoAccion;
	private String documentId;
	private String orgId;
	private String orgUserId;
	private FileReader fileReader;
	private FileReader fileReaderAux;
	
	private long longitud;
	private String contenido;
	
	/**
	 * Metodo que imprime la informacion extraida del archivo
	 */
	public void dump () {
		log.debug ("\tFileName      =["+fileName+"]");
		log.debug ("\tcodigoAccion  =["+codigoAccion+"]");
		log.debug ("\tnroDocumento  =["+documentId+"]");
		log.debug ("\tOrgId 		   =["+orgId+"]");
		log.debug ("\tOrgUserId     =["+orgUserId+"]");
		log.debug ("\tContenido XML =["+fileReader.toString()+"]");
		log.debug ("\tLongitud del archivo XML =["+longitud+"]");
	}

	/**
	 * Metodo encargado de guardar la informacion de un documento recibido en la estructura de directorios.
	 * Retorna true en caso de exito y false en caso contrario.
	 * @param message contenido del documento XML recibido, 
	 * DocumentId numero que identifica al documento, 
	 * carpeta carpeta de destino, 
	 * subCarpeta subcarpeta de Destino
	 * @throws IOException
	 * @return boolean 
	 */
	public boolean guardarArchivo(MQIntegrationMessage message,String DocumentId,String carpetaDestino,String subCarpetaDestino) throws IOException{
		SimpleDateFormat dateFormatter = new SimpleDateFormat("ddMMyyyy_hhmmss");
		FileWriter fw = null;
		PrintWriter out = null;
		boolean resultado=false;
		try{
			setCodigoAccion(message.getAction().trim());
			setDocumentId(DocumentId.trim());
			setOrgId(message.getOrgId().trim());
			setOrgUserId(message.getOrgUserId().trim());
			String fechahora = dateFormatter.format(new java.util.Date());
			String tipoProceso= Helper.getTipoProceso();
			//String extensionArchivo=new String();
			String nombreArchivo=getCodigoAccion()+"_"+getDocumentId()+"_"+getOrgId()+"_"+getOrgUserId()+"_"+fechahora;
			if (carpetaDestino.equalsIgnoreCase(Constantes.DIR_ERROR)){
				nombreArchivo=Constantes.PREFIJOARCHIVOSPROCESADOS+nombreArchivo;
			}
			if (tipoProceso.equalsIgnoreCase(Constantes.PROCESO_XML)){
				setContenido(message.getBody().trim());
				nombreArchivo=nombreArchivo+".xml";
			}
			else
			 	if (tipoProceso.equalsIgnoreCase(Constantes.PROCESO_TXT))
			 		if (carpetaDestino.equalsIgnoreCase(Constantes.DIR_ERROR)){
			 			setContenido(message.getBody().trim());
			 			nombreArchivo=nombreArchivo+".xml";
			 		}
			 		else{			 	
			 			setContenido(message.getBodyCSV().trim());
						nombreArchivo=nombreArchivo+".csv";
			 		}
			setFileName(nombreArchivo);	
			setCompleteFileName( Helper.getXmlInputDirectory() + getFileName());
			if ((Helper.getEmpresa()!=null) && 
					(Helper.getEmpresa().equalsIgnoreCase("B2BuyerServer")))
				setCompleteFileName( Helper.getDirectorioOrigen()+"\\"+message.getBuyerOrgId().trim()+carpetaDestino +subCarpetaDestino+ "\\"+ getFileName());
			else
				setCompleteFileName( Helper.getDirectorioOrigen()+carpetaDestino +subCarpetaDestino+ "\\"+ getFileName());
			fw = new FileWriter(getCompleteFileName(),true);
			out = new PrintWriter(fw);
			out.println(getContenido());
			resultado=true;
		}
		
		catch(IOException ex){
			throw new IOException("Error al intentar guardar el archivo xml:"+getCompleteFileName()+" "+ex);
		}	
		catch(Exception e){
			log.debug("Error al registrar el XML: " + e);
		}
			
		finally {
			try {
				if (fw != null)
					fw.close();
				if (out != null)
					out.close();
			} 
			catch (Exception e) {
			}
		}
		return resultado;
	}
	
	
	/**
	 * Metodo que extrae el contenido del archivo para cargarlo en los atributos de 
	 * la clase.
	 * Retorna true en caso de exito y false en caso contrario.
	 * @param file archivo a analizar.
	 * @return boolean
	 * @throws IncorrectMessageFormatException,FileNotFoundException,IOException
	 */
	public boolean build(File file) throws IncorrectMessageFormatException,FileNotFoundException,Exception,IOException{
		boolean resultado=false;
		int pos1=0,pos2;
		FileReader fis =null;
		try{
			fileName=file.getName();
			completeFileName=file.getAbsolutePath();
			pos2=fileName.indexOf("_",pos1);
			if (pos2==-1){
				log.debug("nombre de archivo XML con formato erroneo:"+fileName);
				throw new IncorrectMessageFormatException("El nombre del archivo XML no tiene el formato apropiado");
			}
			else{
				//Ubicando el codigo de accion:
				codigoAccion= fileName.substring(pos1,pos2);
				log.debug("codigoAccion:"+codigoAccion);
				pos1=pos2+1;
				pos2=fileName.indexOf("_",pos1);
				if (pos2==-1){
					log.debug("nombre de archivo XML con formato erroneo:"+fileName);
					throw new IncorrectMessageFormatException("El nombre del archivo XML no tiene el formato apropiado");
				}
				else{
					//Ubicando el numero de documento:
					documentId=fileName.substring(pos1,pos2);
					log.debug("documentId:"+documentId);					
					pos1=pos2+1;
					pos2=fileName.indexOf("_",pos1);
					if (pos2==-1){
						log.debug("nombre de archivo XML con formato erroneo:"+fileName);
						throw new IncorrectMessageFormatException("El nombre del archivo XML no tiene el formato apropiado");
					}
					else{
						//Ubicando el orgid:
						orgId= fileName.substring(pos1,pos2);
						log.debug("orgId:"+orgId);
						pos1=pos2+1;
						pos2=fileName.indexOf("_",pos1);
						if (pos2==-1){
							log.debug("nombre de archivo XML con formato erroneo:"+fileName);
							throw new IncorrectMessageFormatException("El nombre del archivo XML no tiene el formato apropiado");
						}
						else{
						//Ubicando el orgUserId:
							orgUserId= fileName.substring(pos1,pos2);
							log.debug("UserId:"+orgUserId);
							try{
								log.debug("Ruta completa del archivo: "+completeFileName);
								char buffer[]=new char[1024];
								fis = new FileReader(file.getAbsolutePath()); 
								fileReader = new FileReader(file.getAbsolutePath());
								fileReaderAux = new FileReader(file.getAbsolutePath());
								longitud = file.length();
								int cuenta=0;
								contenido = "";
								 while((cuenta=fis.read(buffer))>0)  {
								 	contenido = contenido+String.valueOf(buffer,0,cuenta);
								 }
								 log.debug("Contenido del archivo: "+contenido);	
							}
							catch(FileNotFoundException ex ){
								throw new FileNotFoundException("No se ha encontrado el archivo:"+fileName);
							}
							catch(IOException ioe) {
								throw new IOException("Error leyendo el contenido del archivo:"+fileName);
							}
							finally {
					            if (fis != null){
					                fis.close();
					                fis = null;
					            }
							}
						}
					}
				}//de si encontro el numero de documento
			}//de si encontro codigo de accion
		}
		catch(Exception e){
			log.debug("Error al obtener la informacion del archivo XML:"+e);
			throw e;
		}
		return resultado;
	}

	/**
	 * Returns the documentId.
	 * @return String
	 */
	public String getDocumentId() {
		return documentId;
	}

	/**
	 * Returns the orgId.
	 * @return String
	 */
	public String getOrgId() {
		return orgId;
	}

	/**
	 * Returns the orgUserId.
	 * @return String
	 */
	public String getOrgUserId() {
		return orgUserId;
	}

	/**
	 * Sets the documentId.
	 * @param documentId The documentId to set
	 */
	public void setDocumentId(String documentId) {
		this.documentId = documentId;
	}

	/**
	 * Sets the orgId.
	 * @param orgId The orgId to set
	 */
	public void setOrgId(String orgId) {
		this.orgId = orgId;
	}

	/**
	 * Sets the orgUserId.
	 * @param orgUserId The orgUserId to set
	 */
	public void setOrgUserId(String orgUserId) {
		this.orgUserId = orgUserId;
	}

	/**
	 * Returns the fileName.
	 * @return String
	 */
	public String getFileName() {
		return fileName;
	}

	/**
	 * Returns the fileReader.
	 * @return FileReader
	 */
	public FileReader getFileReader() {
		return fileReader;
	}

	/**
	 * Sets the fileName.
	 * @param fileName The fileName to set
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * Sets the fileReader.
	 * @param fileReader The fileReader to set
	 */
	public void setFileReader(FileReader fileReader) {
		this.fileReader = fileReader;
	}

	/**
	 * Returns the codigoAccion.
	 * @return String
	 */
	public String getCodigoAccion() {
		return codigoAccion;
	}

	/**
	 * Sets the codigoAccion.
	 * @param codigoAccion The codigoAccion to set
	 */
	public void setCodigoAccion(String codigoAccion) {
		this.codigoAccion = codigoAccion;
	}

	/**
	 * Returns the contenido.
	 * @return String
	 */
	public String getContenido() {
		return contenido;
	}

	/**
	 * Returns the longitud.
	 * @return long
	 */
	public long getLongitud() {
		return longitud;
	}

	/**
	 * Sets the contenido.
	 * @param contenido The contenido to set
	 */
	public void setContenido(String contenido) {
		this.contenido = contenido;
	}

	/**
	 * Sets the longitud.
	 * @param longitud The longitud to set
	 */
	public void setLongitud(long longitud) {
		this.longitud = longitud;
	}

	/**
	 * Returns the completeFileName.
	 * @return String
	 */
	public String getCompleteFileName() {
		return completeFileName;
	}

	/**
	 * Sets the completeFileName.
	 * @param completeFileName The completeFileName to set
	 */
	public void setCompleteFileName(String completeFileName) {
		this.completeFileName = completeFileName;
	}
	
	public boolean closeFileReader(){
		try{
			//if (fileReader != null)
				fileReader.close();
			//if (fileReaderAux != null)
				fileReaderAux.close();
			return true;
		}
		catch(IOException e){
			return false;			
		}		
	}
	/**
	 * Returns the fileReaderAux.
	 * @return FileReader
	 */
	public FileReader getFileReaderAux() {
		return fileReaderAux;
	}

}
